/*
 * Transliteration Table
 *
 * ZhihuiJin <zhihuijin@gmail.com>
 * vim: ts=4 sw=4 sts=4 et tw=78:
 * Sat Sep 15 16:22:13 JST 2007
 */ 

package jp.ac.utokyo.pinyomi;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;

/** Transliteration table bewteen Kanji and Hanzi */
public abstract class TransliterationTable extends AbstractTable {

    /** cognate-based transliteration file */
    private String cognateFileName;

    /** whether read cognate pair in reversed direction */
    private boolean   reversed;

    /** shape-based transliteration file */
    private String shapeFileName; 


    /** Constructor 
     * @throws IOException */
	public TransliterationTable() throws IOException {
		super();
	}
	
	@Override
	public void preSet() {
		if( this instanceof Hanzi2KanjiTable ){
	        cognateFileName = Settings.KanjiHanziCognates;
	        shapeFileName   = Settings.HanziKanjiShapeMapping;
	        reversed        = true;
		} else if (this instanceof Kanji2HanziTable){
	        cognateFileName = Settings.KanjiHanziCognates;
	        shapeFileName   = Settings.KanjiHanziShapeMapping;
	        reversed        = false;
		}
		
	}

	@Override
	protected HashMap<String, Pair> readfile() throws IOException {
		System.out.println("Reading transliteration table ...");
		map = new HashMap<String, Pair>();
        readCognateFile(cognateFileName, reversed);
        readShapeFile(shapeFileName);

        normalize(); // normalize the weight

        return map;
    }


    /** Read cognate-based transliteration table */
    private void readCognateFile(String fileName, boolean reversed) throws IOException {
    	System.out.println("Reading cognate file ...");
        BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(fileName), "UTF-8"));
		String strLine;
		while((strLine = in.readLine()) != null){
            if (strLine.startsWith("#"))
                continue;
            if (strLine.trim().equals(""))
                continue;

            String key, value;
            String[] fields = strLine.split("\\s+");
            if (reversed) {
                key = fields[1]; 
                value = fields[0];
            } else {
                key = fields[0]; 
                value = fields[1];
            }

            if (!map.containsKey(key)){
                Pair pair = new Pair();
                pair.addTriple(value, 1.0, "C");
                map.put(key, pair);
            } else {
                map.get(key).addTriple(value, 1.0, "C");
            }
        }
    }


    /** Read shape-based transliteration table */
	public void readShapeFile(String fileName) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(fileName), "UTF-8"));
        HashMap<String, Pair> remap = new HashMap<String, Pair>();

        String strLine;
		while((strLine = in.readLine()) != null){
            if (strLine.startsWith("#"))
                continue;
            if (strLine.trim().equals(""))
                continue;

            String hanChar, tag;
            Pair pair = new Pair();
            String[] fields = strLine.split("\\s+");
            
        	String key;
        	Pair remapPair;
            if (fields[0].equals("m")) { //expand remapping 
                key = fields[1].substring(0, 1);
                for (int i = 2; i < fields.length; i++) {
                    hanChar = fields[i].substring(0, 1);
                    tag     = fields[i].substring(1);
                    if (tag.equals("m")) {
                    	remapPair = remap.get(hanChar);
                        for (int j = 0; j < remapPair.size(); j++)
                            pair.addTriple(remapPair.getKey(j), remapPair.getVal(j), remapPair.getTag(j));
                    } 
                    else {
                        pair.addTriple(hanChar, 1.0, tag);
                    }
                }
                remap.put(key, pair);
            } 
            else {
                key = fields[1];
                for (int i = 2; i < fields.length; i++) {
                    hanChar = fields[i].substring(0, 1);
                    tag     = fields[i].substring(1);
                    if (tag.equals("m")) {
                        remapPair = remap.get(hanChar);
                        for (int j = 0; j < remapPair.size(); j++)
                            pair.addTriple(remapPair.getKey(j), remapPair.getVal(j), remapPair.getTag(j));
                    } 
                    else {
                        pair.addTriple(hanChar, 1.0, tag);
                    }
                }

                // Update map
                if (!map.containsKey(key))
                    map.put(key, pair); 
                else 
                    map.get(key).addTriple(pair);
            }
        }
    }
};

